This invention relates to computer security. More particularly, the present application relates to apparatus and methods for reducing or eliminating the adverse effects of malicious computer program code introduced by intrusions into computer systems and otherwise. Still more particularly, the present invention relates to reducing or eliminating the effects of computer viruses, worms and other malicious intrusions through the use of program stack protection techniques.
Many violations of computer security depend upon exploiting a mistake or oversight by the programmer(s) of an application or firmware on the target computer. Such nefarious activities as the introduction of viruses or worms into unsuspecting computers, or theft of computer-based data or services have become more frequent and costly in recent years.
Common practice in designing and manufacturing computer CPUs, including CPU chips, is to include within the system a set of memory locations or registers to be used as an area for temporarily storing information. Such memory or registers are referred to as a stack into which operands are pushed down (stored) and popped off (unloaded) on a last-in, first-out (LIFO) basis. The stack is conveniently divided into stack frames, usually related to individual program portions or constructs known as procedures, functions, threads, or the like. A modular program, e.g., one having a plurality of procedures, will have multiple stack frames within a particular stack when a given procedure calls another procedure, e.g., returning jump, or calls itself, e.g., a reentrant procedure call.
One of the most common hacker attacks (used, e.g., by the 2002 ‘Code Red’ and 2003 ‘SQL Slammer’ worms) is the “buffer overrun attack”. A buffer overrun attack is a technique in which the attacker supplies an overly large text string or array to a vulnerable system that fails to check and control the size of the input. The attacking string is then copied into a buffer, including a stack buffer that is too small to hold it. The excess string data then spills over from the buffer, thus overwriting other portions of memory, including those portions containing variables or flow control pointers on the process stack.
Under many operating conditions, a computer buffer overrun will cause the running process to crash or simply malfunction in a random fashion. In the case of a malicious buffer overrun attack, however, the attacker often carefully constructs the input data so that the overflow portion is not random. Instead, specific values are chosen to force the process to perform actions of the attacker's choosing. Numerous studies have been undertaken to understand and defend against buffer overrun and related attacks. See, for example, Zou, C C, et al., “Monitoring and Early Warning for Internet Worms,” Proceedings of the 10th ACM conference on Computer and communication security, October, 2003; and Weaver, N, et al., “A Taxonomy of Computer Worms,” WORM '03, Oct. 27, 2003. Also of interest in understanding buffer overflows is the paper by Neiliβen, J entitled “Buffer Overflows for Dummies,” SANS Institute, 2002, available at http://www.sans.org/rr/papers/60/481.pdf, which paper is hereby incorporated by reference in the present disclosure. This problem is further treated in Donaldson, M. J., “Inside the Buffer Overflow Attack Mechanism, Method and Prevention, Feb. 6, 2003, available at http://www.sans.org/rr/papers/46/386.pdf.
Various techniques for protecting against such buffer-overrun attacks have been proposed (e.g., stack guarding, run-time length checking, and the like), but all either impose a severe performance penalty on a system, are vulnerable to attack themselves, or both. Some require the original source code of a software system to be partially rewritten or translated into another language, a prohibitively costly effort.
In some aspects, operations involving execution stacks and associated heaps have proven problematic in other contexts. Therefore, a number of computer architecture approaches have included adaptations of instruction stack and heap organizations, to achieve specific memory management goals. An early technique for creating stacks of appropriate length for a given procedure or the like is described in U.S. Pat. No. 4,524,416, which patent is hereby incorporated by reference as if set forth in its entirety herein.
U.S. Pat. No. 6,442,661 describes another stack architecture that seeks to achieve tuning of memory management operations by assigning memory blocks of varying size in varying parts of a memory. U.S. Pat. No. 6,058,457 discloses a system in which plural stacks are employed for storing component parts, e.g., operands and local variables (or arguments), of stack frames in different stack structures. A goal of this latter approach is to facilitate access to the several parts of a stack frame. U.S. Pat. No. 6,557,093 discloses a stack-oriented computer structure with two stacks, each storing words of different length. In the last-noted patent, a stack of shorter word-length elements is typically used for numerical operands, while a stack having longer word length is used for addresses for operands.
An unresolved problem remains, however: how can stack architecture be adapted to help in countering attacks by viruses, worms or other malicious invaders that exploit known stack operation to cause overflow of buffers, thereby to alter operating computer code in the areas into which overflow occurs.